package com.ecloud.hbase.service.impl;

import com.alibaba.fastjson.JSON;
import com.ecloud.common.ResultEnum;
import com.ecloud.common.exception.ServerException;
import com.ecloud.common.util.TimeUtil;
import com.ecloud.hbase.entities.TdbDailyHbaseTable;

import com.ecloud.hbase.entities.TdbEnvironmentPresentHbaseTable;
import com.ecloud.hbase.entities.TdbPresentHbaseTable;
import com.ecloud.hbase.service.HbaseService;
import com.ecloud.hbase.service.HbaseTdbService;
import com.ecloud.trend.entities.TdbDaily;
import com.ecloud.trend.vo.TdbEnvironmentPresentVo;
import com.ecloud.trend.vo.TdbPresentVo;
import org.apache.hadoop.hbase.util.Bytes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author sheldon
 */
@Service
public class HbaseTdbServiceImpl implements HbaseTdbService {

    @Autowired
    HbaseService hbaseService;

    @Override
    public List<TdbDaily> getDailyAndParse(String rowKey) {
        TdbDailyHbaseTable table = hbaseService.getData(TdbDailyHbaseTable.class, rowKey);
        if (table == null || table.getDailyMap() == null || table.getDailyMap().isEmpty()) {
            throw new ServerException(ResultEnum.REQUEST_NULL);
        }
        Map<String, String> map = table.getDailyMap();
        List<TdbDaily> result = new ArrayList<>();
        for (String json : map.values()) {
            TdbDaily tdbDaily = JSON.parseObject(json, TdbDaily.class);
            result.add(tdbDaily);
        }
        return result;
    }

    @Override
    public <T extends TdbPresentHbaseTable> void setBuildingPresentData(Class<T> tableClass, List<TdbPresentVo> tdbPresentVos) {
        Map<String, Map<String, String>> map = tdbPresentVosToBuildMap(tdbPresentVos);
        for (Map.Entry<String, Map<String, String>> entry : map.entrySet()) {
            T t;
            try {
                t = tableClass.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
                throw new ServerException(ResultEnum.SYS_ERROR, e.getMessage());
            }
            Map<String, String> mapTo = entry.getValue();
            String buildingName = entry.getKey();
            if (buildingName == null || buildingName.isEmpty()) {
                buildingName = "default";
            }
            t.setBuildingMap(mapTo);
            hbaseService.setData(t, buildingName);
        }
    }


    /**
     * 转换vos到Map
     *
     * @param tdbPresentVos {@link TdbPresentVo}
     * @return map < buildingName < time , listJson > >
     * @author Squbi
     * @date 2021/7/23 17:28
     */
    private Map<String, Map<String, String>> tdbPresentVosToBuildMap(List<TdbPresentVo> tdbPresentVos) {
        Map<String, Map<String, String>> map = new HashMap<>();
        Map<String, List<TdbPresentVo>> buildingMap = new HashMap<>();
        for (TdbPresentVo tdbPresentVo : tdbPresentVos) {
            String buildingName = tdbPresentVo.getBuildName();
            buildingMap.computeIfAbsent(buildingName, k -> new ArrayList<>());
            List<TdbPresentVo> vos = buildingMap.get(buildingName);
            vos.add(tdbPresentVo);
        }
        String now = TimeUtil.toWholeTime(TimeUtil.now());
        for (Map.Entry<String, List<TdbPresentVo>> entry : buildingMap.entrySet()) {
            HashMap<String, String> innerMap = new HashMap<>();
            innerMap.put(now, JSON.toJSONString(entry.getValue()));
            map.put(entry.getKey(), innerMap);
        }
        return map;
    }

    @Override
    public <T extends TdbPresentHbaseTable> Map<String, List<TdbPresentVo>> getBuildingPresentAllData(Class<T> tableClass, String buildingName) {
        TdbPresentHbaseTable data = hbaseService.getData(tableClass, buildingName);
        if (data == null) {
            throw new ServerException(ResultEnum.REQUEST_NULL);
        }
        return data.toPresentMapping();
    }

    @Override
    public <T extends TdbPresentHbaseTable> Map<String, List<TdbPresentVo>> getBuildingPresentData(Class<T> tableClass, String buildingName, String keyTime) {
        if (keyTime.length() != TimeUtil.DATE_TIME_FORMAT_STANDARD.length()) {
            throw new ServerException(ResultEnum.ARGS_ERR, "时间戳长度有误 标准为yyyyMMddHHmm 共12位");
        }
        String finalKeyTime = TimeUtil.toWholeTime(keyTime);
        TdbPresentHbaseTable data = hbaseService.getData(tableClass, buildingName, inner -> {
            inner.addColumn(Bytes.toBytes("buildingMap"), Bytes.toBytes(finalKeyTime));
            return inner;
        });
        if (data == null) {
            throw new ServerException(ResultEnum.REQUEST_NULL);
        }
        return data.toPresentMapping();
    }

    @Override
    public void setEnvironmentPresentData(List<TdbEnvironmentPresentVo> tdbPresentVos) {
        String now = TimeUtil.toWholeTime(TimeUtil.now());
        Map<String, String> map = new HashMap<>();
        map.put(now, JSON.toJSONString(tdbPresentVos));
        TdbEnvironmentPresentHbaseTable table = new TdbEnvironmentPresentHbaseTable(map);
        hbaseService.setData(table, now);
    }

    @Override
    public List<TdbEnvironmentPresentVo> getEnvironmentPresentData(String timeKey) {
        TdbEnvironmentPresentHbaseTable data = hbaseService.getData(TdbEnvironmentPresentHbaseTable.class, timeKey);
        Map<String, String> dataMap = data.getDataMap();
        if (dataMap == null || dataMap.isEmpty()) {
            throw new ServerException(ResultEnum.REQUEST_NULL);
        }
        String json = dataMap.get(timeKey);
        return JSON.parseArray(json, TdbEnvironmentPresentVo.class);
    }
}
